package com.michaelbulava.TFS.ui.dialogs.connect;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
import com.michaelbulava.TFS.Messages;
import com.michaelbulava.TFS.log.FileLogger;
import com.michaelbulava.TFS.persistence.IdeaPersistenceStoreProvider;
import com.microsoft.tfs.core.credentials.CachedCredentials;
import com.microsoft.tfs.core.credentials.CredentialsManager;
import com.microsoft.tfs.core.credentials.CredentialsManagerFactory;
import com.microsoft.tfs.core.httpclient.Credentials;
import com.microsoft.tfs.core.httpclient.PreemptiveUsernamePasswordCredentials;
import com.microsoft.tfs.core.httpclient.UsernamePasswordCredentials;
import com.microsoft.tfs.util.Check;
import com.microsoft.tfs.util.listeners.SingleListenerFacade;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * Created by mbulava on 5/6/2015.
 */
public class CredentialsDialog extends DialogWrapper implements CredentialsCompleteDialog {
    private static final Logger log = FileLogger.getInstance(CredentialsDialog.class);
    private JPanel contentPane;
    private JButton buttonOK;
    private JButton buttonCancel;
    private JEditorPane errorText;
    private JTextField userNameText;
    private JPasswordField passwordText;
    private JCheckBox savePasswordCheckBox;

    private final boolean isPreEmptiveUser;

    boolean isNeedCursorChange=true;
    private final SingleListenerFacade credentialsCompleteListeners = new SingleListenerFacade(CredentialsCompleteListener.class);


    private Credentials credentials;
    private URI serverURI;
    private boolean alwaysSavePassword = false;

    public CredentialsDialog(Project project) {
        this(project, null);
    }

    public CredentialsDialog(Project project, URI serverURI){
       this(project,serverURI, false);
    }

    public CredentialsDialog(JComponent owner, URI serverURI){
        this(owner, serverURI, false);
    }

    public CredentialsDialog(Project project, URI serverURI, boolean FedAuthRequired){
        super(project, false, IdeModalityType.PROJECT);
        this.isPreEmptiveUser = FedAuthRequired;
        initialize();
        if (serverURI != null)
            setServerURI(serverURI);
    }


    public CredentialsDialog(JComponent owner, URI serverURI, boolean FedAuthRequired){
        super(owner, false);
        this.isPreEmptiveUser = FedAuthRequired;
        initialize();
        if (serverURI != null)
            setServerURI(serverURI);
    }

    private void initialize(){
        setModal(true);
        setAutoAdjustable(true);
        this.createContentPane();

        setupUI();
        init();
        setAutoAdjustable(true);

        getWindow().addWindowStateListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                ((CredentialsCompleteListener) credentialsCompleteListeners.getListener()).credentialsComplete();
            }
        });

    }


    /*public CredentialsCompleteDialog(Project project){
        super(project, false, IdeModalityType.PROJECT);
        initialize();
    }

    public CredentialsCompleteDialog(JComponent owner){
        super(owner, false);
        initialize();
    }

    private void initialize(){

    }*/



    @Override
    public void addCredentialsCompleteListener(CredentialsCompleteListener listener) {
        this.credentialsCompleteListeners.addListener(listener);
    }

    private void setupUI(){
        setTitle(Messages.getString("CredentialsDialog.DialogTitleFormat"));
        

        contentPane = new JPanel();
        contentPane.setLayout(new GridLayoutManager(1, 1, new Insets(10, 10, 10, 10), -1, -1));
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new GridLayoutManager(5, 2, new Insets(0, 0, 0, 0), -1, -1));
        contentPane.add(panel1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER,
                GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        errorText = new JEditorPane();
        errorText.setEditable(false);
        errorText.setEditorKit(JEditorPane.createEditorKitForContentType("text/html"));
        errorText.addHyperlinkListener(new myHyperlinkListener());
        /* {
            public void setCursor(Cursor cursor) {
                if (isNeedCursorChange) {
                    super.setCursor(cursor);
                }
            }
        };*/
        panel1.add(errorText, new GridConstraints(0, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
                GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(150, 50),
                null, 0, false));
        final Spacer spacer1 = new Spacer();
        panel1.add(spacer1, new GridConstraints(4, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL,
                1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
        final JLabel label1 = new JLabel();
        label1.setText(Messages.getString("CredentialsDialog.UserNameLabel"));
        panel1.add(label1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
                GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        userNameText = new JTextField();
        panel1.add(userNameText, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST,
                GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED,
                null, new Dimension(150, -1), null, 0, false));
        final JLabel label2 = new JLabel();
        label2.setText(Messages.getString("CredentialsDialog.PasswordLabel"));
        panel1.add(label2, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
                GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        passwordText = new JPasswordField();
        panel1.add(passwordText, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST,
                GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED,
                null, new Dimension(150, -1), null, 0, false));
        savePasswordCheckBox = new JCheckBox();
        savePasswordCheckBox.setText(Messages.getString("CredentialsDialog.SavePasswordLabel"));
        panel1.add(savePasswordCheckBox, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_WEST,
                GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
    }

    public void setServerURI(URI serverURI){
        Check.notNull(serverURI, "serverURI");
        this.serverURI = serverURI;
    }

    public void setAllowSavePassword(boolean allowSavePassword) {
        this.savePasswordCheckBox.setVisible(allowSavePassword);
    }

    public void setAlwaysSavePassword(boolean alwaysSavePassword) {
        this.alwaysSavePassword = alwaysSavePassword;
    }

    public URI getServerURI() {
        return this.serverURI;
    }


    public void setErrorMessage(String text) {
        //errorText.removeMouseListener(VSOClick);
        if (isPreEmptiveUser) {
            //MyHTMLEditorKit kit=new MyHTMLEditorKit();


        }
        this.errorText.setText(text);

        //if (isPreEmptiveUser)
        //    errorText.addMouseListener(VSOClick);
    }

    public void setCredentials(Credentials credentials) {
        this.credentials = credentials;
        if (this.credentials != null && this.credentials instanceof UsernamePasswordCredentials) {
            userNameText.setText(((UsernamePasswordCredentials) this.credentials).getUsername());
            passwordText.setText(((UsernamePasswordCredentials) this.credentials).getPassword());
        }
    }

    public boolean isSavePasswordChecked() {
        return savePasswordCheckBox.isSelected();
    }

    @Override
    public Credentials getCredentials() {
        return this.credentials;
    }

    /**
     * Factory method. It creates panel with dialog options. Options panel is located at the center of the dialog's
     * content pane. The implementation can return <code>null</code> value. In this case there will be no options
     * panel.
     *
     * @return center panel
     */
    @Nullable
    @Override
    protected JComponent createCenterPanel() {
        return contentPane;
    }

    @Override
    protected void doOKAction() {
        if (!this.isPreEmptiveUser )
            this.credentials = new UsernamePasswordCredentials(this.userNameText.getText(),
                    this.passwordText.getText());
        else
            this.credentials = new PreemptiveUsernamePasswordCredentials(this.userNameText.getText(),
                    this.passwordText.getText());
        if (this.savePasswordCheckBox.isSelected()) {
            CredentialsManager cm = CredentialsManagerFactory.getCredentialsManager(IdeaPersistenceStoreProvider.INSTANCE);
            if (!cm.setCredentials(new CachedCredentials(serverURI, this.credentials))) {
                Messages.showErrorDialog(contentPane, "Could not save your credentials.",//Messages.getString("CredentialsDialog.SavePasswordFailedTitle"),
                        "Credential storage failed");//Messages.getString("CredentialsDialog.SavePasswordFailedMessage"));
                return;
            }
        }

        super.doOKAction();
        ((CredentialsCompleteListener)this.credentialsCompleteListeners.getListener()).credentialsComplete();
    }

    @Override
    public void doCancelAction(){
        super.doCancelAction();;
        //((CredentialsCompleteListener)this.credentialsCompleteListeners.getListener()).credentialsComplete();
    }



    private class myHyperlinkListener implements HyperlinkListener {
        public void hyperlinkUpdate(HyperlinkEvent e) {
            if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
                try {
                    Desktop.getDesktop().browse(e.getURL().toURI());
                    //edit.setPage(e.getURL());
                } catch (IOException e1) {
                    e1.printStackTrace();
                } catch (URISyntaxException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
//
//    public class MyHTMLEditorKit extends HTMLEditorKit {
//
//        MyLinkController handler=new MyLinkController();
//        public void install(JEditorPane c) {
//            MouseListener[] oldMouseListeners=c.getMouseListeners();
//            MouseMotionListener[] oldMouseMotionListeners=c.getMouseMotionListeners();
//            super.install(c);
//            //the following code removes link handler added by original
//            //HTMLEditorKit
//
//            for (MouseListener l: c.getMouseListeners()) {
//                c.removeMouseListener(l);
//            }
//            for (MouseListener l: oldMouseListeners) {
//                c.addMouseListener(l);
//            }
//
//            for (MouseMotionListener l: c.getMouseMotionListeners()) {
//                c.removeMouseMotionListener(l);
//            }
//            for (MouseMotionListener l: oldMouseMotionListeners) {
//                c.addMouseMotionListener(l);
//            }
//
//            //add out link handler instead of removed one
//            c.addMouseListener(handler);
//            c.addMouseMotionListener(handler);
//        }
//
//
//
//        public class MyLinkController extends LinkController {
//
//            public void mouseClicked(MouseEvent e) {
//                JEditorPane editor = (JEditorPane) e.getSource();
//
//                if (editor.isEditable() && SwingUtilities.isLeftMouseButton(e)) {
//                    if (e.getClickCount()==2) {
//                        editor.setEditable(false);
//                        super.mouseClicked(e);
//                        editor.setEditable(true);
//                    }
//                }
//
//            }
//            public void mouseMoved(MouseEvent e) {
//                JEditorPane editor = (JEditorPane) e.getSource();
//
//                if (editor.isEditable()) {
//                    isNeedCursorChange=false;
//                    editor.setEditable(false);
//                    isNeedCursorChange=true;
//                    super.mouseMoved(e);
//                    isNeedCursorChange=false;
//                    editor.setEditable(true);
//                    isNeedCursorChange=true;
//                }
//            }
//
//        }
//    }

}
